package config

import (
	"log"
	"time"

	"github.com/spf13/viper"
)

type Config struct {
	GitPath            string        `yaml:"git_path" mapstructure:"git_path"`
	ServerEndPoint     string        `yaml:"server_endpoint" mapstructure:"server_endpoint"`
	ServerPort         int           `yaml:"server_port" mapstructure:"server_port"`
	PreReceiveTimeout  time.Duration `yaml:"pre_receive_timeout" mapstructure:"pre_receive_timeout"`
	PostReceiveTimeout time.Duration `yaml:"post_receive_timeout" mapstructure:"post_receive_timeout"`
	PostFetchTimeout   time.Duration `yaml:"post_fetch_timeout" mapstructure:"post_fetch_timeout"`

	PackObjects struct {
		Timeout          time.Duration `yaml:"timeout" mapstructure:"timeout"`
		CacheMode        string        `yaml:"cache_mode" mapstructure:"cache_mode"`
		CacheWaitTimeout time.Duration `yaml:"cache_wait_timeout" mapstructure:"cache_wait_timeout"`
		CacheHitNotice   string        `yaml:"cache_hit_notice" mapstructure:"cache_hit_notice"`
	} `yaml:"pack_objects" mapstructure:"pack_objects"`

	Alog struct {
		FilePath    string `yaml:"log_file" mapstructure:"log_file"`
		Level       string `yaml:"log_level" mapstructure:"log_level"`
		MaxSize     int    `yaml:"log_max_size" mapstructure:"log_max_size"`
		MaxBackup   int    `yaml:"log_max_backup" mapstructure:"log_max_backup"`
		MaxAge      int    `yaml:"log_max_age" mapstructure:"log_max_age"`
		Compress    bool   `yaml:"log_compress" mapstructure:"log_compress"`
		Stdout      bool   `yaml:"log_stdout" mapstructure:"log_stdout"`
		ServiceName string `yaml:"log_service_name" mapstructure:"log_service_name"`
	} `yaml:"alog" mapstructure:"alog"`
}

var Cfg Config

type PreSendPackOption struct {
	Have   int32
	Filter int32
	Depth  int32
}

var PreSendPackOpt PreSendPackOption

// LoadConfig parses config file
func LoadConfig() {
	viper.SetConfigName("git-hooks")
	viper.SetConfigType("yaml")
	viper.AddConfigPath("$HOME")
	viper.AddConfigPath("/home/git/config")

	viper.SetDefault("server_endpoint", "localhost")
	viper.SetDefault("server_port", "58081")
	viper.SetDefault("pre_receive_timeout", "30s")
	viper.SetDefault("post_receive_timeout", "30s")
	viper.SetDefault("post_fetch_timeout", "30s")

	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			log.Fatalf("config file not found: %v", err)
		} else {
			log.Fatalf("failed to load config: %v", err)
		}
	}

	if err := viper.Unmarshal(&Cfg); err != nil {
		log.Fatalf("failed to unmarshal config: %v", err)
	}

	if Cfg.GitPath == "" {
		Cfg.GitPath = "/usr/bin/git"
	}

	if Cfg.PackObjects.Timeout == 0 {
		Cfg.PackObjects.Timeout = time.Hour
	}
	if Cfg.PackObjects.CacheMode == "" {
		Cfg.PackObjects.CacheMode = "nocache"
	}
	if Cfg.PackObjects.CacheWaitTimeout == 0 {
		Cfg.PackObjects.CacheWaitTimeout = time.Second * 5
	}
	if Cfg.PackObjects.CacheHitNotice == "" {
		Cfg.PackObjects.CacheHitNotice = "Accelerated through AGit cache engine."
	}
}

func Load(cfg Config) {
	Cfg = cfg
}
